package com.dmz.workflow.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dmz.workflow.constant.MatrixRoleMaintainType;
import com.dmz.workflow.param.*;
import com.dmz.workflow.service.ProcessMatrixService;
import com.dmz.workflow.vo.*;
import com.dmz.workflow.wrapper.MemberFeignWrapper;
import com.echronos.commons.Result;
import com.echronos.commons.enums.ErrorMsgEnum;
import com.echronos.commons.utils.CopyObjectUtils;
import com.echronos.system.resp.member.MemberDetailsResp;
import com.dmz.workflow.entity.ProcessMatrix;
import com.dmz.workflow.entity.ProcessMatrixMember;
import com.dmz.workflow.manager.WorkflowProcessMatrixManager;
import com.dmz.workflow.manager.WorkflowProcessMatrixMemberManager;
import com.echronos.workflow.param.*;
import com.echronos.workflow.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: zhouguoqing
 * @date: 2021/09/28/15:49
 */
@Slf4j
@Service
public class ProcessMatrixServiceImpl implements ProcessMatrixService {

    @Autowired
    private WorkflowProcessMatrixManager workflowProcessMatrixManager;

    @Autowired
    private WorkflowProcessMatrixMemberManager workflowProcessMatrixMemberManager;

    @Autowired
    private MemberFeignWrapper memberFeignWrapper;


    @Override
    public Result<List<WorkflowProcessMatrixVO>> getMatrixRoleList(Integer companyId) {
        List<ProcessMatrix> workflowProcessMatrices = workflowProcessMatrixManager
                .getBaseMapper()
                .selectList(new QueryWrapper<ProcessMatrix>().lambda()
                        .eq(ProcessMatrix::getCompanyId, companyId)
                        .eq(ProcessMatrix::getIsDeleted, 0));

        if (CollectionUtils.isEmpty(workflowProcessMatrices)) {
            return Result.build(new ArrayList<>());
        }

        return Result.build(CopyObjectUtils.copyAlistToBlist(workflowProcessMatrices, WorkflowProcessMatrixVO.class));
    }

    @Override
    public Result<WorkflowProcessMatrixVO> addMatrixRole(AddMatrixRoleParam param) {
        ProcessMatrix processMatrix = CopyObjectUtils.copyAtoB(param, ProcessMatrix.class);
        WorkflowMatrixBeanVO workflowMatrixBeanVO = new WorkflowMatrixBeanVO();
        workflowMatrixBeanVO.setCompany(MatrixRoleMaintainType.MATRIX_ROLE_MAINTAIN_COMPANY.value);
        processMatrix.setRoleMaintainence(JSON.toJSONString(workflowMatrixBeanVO));
        log.info("新增矩阵角色processMatrix:{}", processMatrix);
        if (workflowProcessMatrixManager.save(processMatrix)) {
            return Result.build(CopyObjectUtils.copyAtoB(processMatrix, WorkflowProcessMatrixVO.class));
        }
        return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
    }

    @Override
    public Result<WorkflowProcessMatrixVO> saveMatrixRole(SaveMatrixRoleParam param) {
        ProcessMatrix processMatrix = workflowProcessMatrixManager.getById(param.getMatrixId());
        if (StringUtils.isEmpty(processMatrix)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        processMatrix.setName(!StringUtils.isEmpty(param.getName()) ? param.getName() : processMatrix.getName());
        processMatrix.setContent(!StringUtils.isEmpty(param.getContent()) ? param.getContent() : processMatrix.getName());
        log.info("修改矩阵角色workflowProcessMatrix:{}", processMatrix);
        workflowProcessMatrixManager.updateById(processMatrix);
        return Result.build(CopyObjectUtils.copyAtoB(processMatrix, WorkflowProcessMatrixVO.class));
    }

    @Override
    public Result<WorkflowMatrixVO> getMatrixRoleMaintainList(Integer matrixId) {
        ProcessMatrix processMatrix = workflowProcessMatrixManager.getById(matrixId);
        if (StringUtils.isEmpty(processMatrix)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        WorkflowMatrixVO workflowMatrixVO = JSONUtil.toBean(processMatrix.getRoleMaintainence(), WorkflowMatrixVO.class);
        workflowMatrixVO.setMatrixId(processMatrix.getId());
        log.info("获取矩阵人员维护workflowMatrixVO:{}", workflowMatrixVO);
        return Result.build(workflowMatrixVO);
    }

    @Override
    public Result<WorkflowMatrixVO> saveMatrixRoleMaintain(SaveMatrixRoleMaintainParam param) {
        ProcessMatrix processMatrix = workflowProcessMatrixManager.getById(param.getMatrixId());
        if (StringUtils.isEmpty(processMatrix)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        // 检测矩阵名称是否重复
        if (!CollectionUtils.isEmpty(param.getRoleNames())) {
            Set<String> roleNames = new HashSet<>(param.getRoleNames());
            if (roleNames.size() != param.getRoleNames().size()) {
                throw new FlowableException("矩阵角色名称重复");
            }
        }

        WorkflowMatrixBeanVO workflowMatrixBeanVO = CopyObjectUtils.copyAtoB(param, WorkflowMatrixBeanVO.class);
        processMatrix.setRoleMaintainence(JSON.toJSONString(workflowMatrixBeanVO));
        log.info("保存矩阵人员维护processMatrix:{}", processMatrix);
        if (!workflowProcessMatrixManager.updateById(processMatrix)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        Map<String, Object> columnMap = new HashMap<>(2);
        columnMap.put("matrix_id", processMatrix.getId());
        columnMap.put("is_deleted", 0);
        List<ProcessMatrixMember> processMatrixMembers = workflowProcessMatrixMemberManager.listByMap(columnMap);
        if (!CollectionUtils.isEmpty(processMatrixMembers)) {
            if (!CollectionUtils.isEmpty(param.getRoleNames())) {
                for (ProcessMatrixMember processMatrixMember : processMatrixMembers) {
                    // 检测部门
                    if (StringUtils.isEmpty(param.getDepartment())) {
                        processMatrixMember.setDepartment("");
                        processMatrixMember.setDepartmentId(null);
                    }

                    if (!StringUtils.isEmpty(processMatrixMember.getRoleMember())) {
                        List<PeopleMaintainMemberVO> peopleMaintainMemberVOList = this.jsonTransitionPeople(processMatrixMember.getRoleMember());
                        List<PeopleMaintainMemberVO> jsonPeopleMaintainMemberVOList = new ArrayList<>();
                        for (PeopleMaintainMemberVO peopleMaintainMemberVO : peopleMaintainMemberVOList) {
                            if (param.getRoleNames().contains(peopleMaintainMemberVO.getRoleName())) {
                                jsonPeopleMaintainMemberVOList.add(peopleMaintainMemberVO);
                            }
                        }
                        // 将Json数据进行重新排序
                        Map<String, PeopleMaintainMemberVO> maintainMemberMap = jsonPeopleMaintainMemberVOList.stream()
                                .collect(Collectors.toMap(PeopleMaintainMemberVO::getRoleName, p -> p));
                        peopleMaintainMemberVOList.clear();
                        for (String roleName : param.getRoleNames()) {
                            PeopleMaintainMemberVO peopleMaintainMemberVO = maintainMemberMap.get(roleName);
                            if (!StringUtils.isEmpty(peopleMaintainMemberVO)) {
                                peopleMaintainMemberVOList.add(peopleMaintainMemberVO);
                            }
                        }
                        processMatrixMember.setRoleMember(JSON.toJSONString(peopleMaintainMemberVOList));
                    }
                }
            } else {
                processMatrixMembers.forEach(processMatrixMember -> {
                    // 检测部门
                    if (StringUtils.isEmpty(param.getDepartment())) {
                        processMatrixMember.setDepartment("");
                        processMatrixMember.setDepartmentId(null);
                    }

                    if (!StringUtils.isEmpty(processMatrixMember.getRoleMember())) {
                        processMatrixMember.setRoleMember("");
                    }
                });
            }
            workflowProcessMatrixMemberManager.updateBatchById(processMatrixMembers);
        }
        WorkflowMatrixVO workflowMatrixVO = CopyObjectUtils.copyAtoB(workflowMatrixBeanVO, WorkflowMatrixVO.class);
        workflowMatrixVO.setMatrixId(processMatrix.getId());
        return Result.build(workflowMatrixVO);
    }

    @Override
    public Result<ProcessMatrixMemberVO> addMatrixPeopleMaintain(AddMatrixPeopleMaintainParam param) {
        ProcessMatrixMember processMatrixMember = CopyObjectUtils.copyAtoB(param, ProcessMatrixMember.class);
        if (!CollectionUtils.isEmpty(param.getAddPeopleMaintainParams())) {
            processMatrixMember.setRoleMember(JSON.toJSONString(param.getAddPeopleMaintainParams()));
        }
        if (workflowProcessMatrixMemberManager.save(processMatrixMember)) {
            ProcessMatrixMemberVO processMatrixMemberVO = CopyObjectUtils.copyAtoB(processMatrixMember, ProcessMatrixMemberVO.class);
            processMatrixMemberVO.setPeopleMaintainMembers(this.jsonTransitionPeople(processMatrixMember.getRoleMember()));
            return Result.build(processMatrixMemberVO);
        }
        return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
    }

    @Override
    public List<PeopleMaintainMemberVO> jsonTransitionPeople(String roleMember) {
        if (StringUtils.isEmpty(roleMember)) {
            return new ArrayList<>();
        }
        List<PeopleMaintainMemberVO> peopleMaintainMemberVOList = JSONArray.parseArray(roleMember, PeopleMaintainMemberVO.class);
        if (!CollectionUtils.isEmpty(peopleMaintainMemberVOList)) {
            for (PeopleMaintainMemberVO peopleMaintainMemberVO : peopleMaintainMemberVOList) {
                List<Integer> memberIds = peopleMaintainMemberVO.getPeopleMaintainMemberParams().stream()
                        .map(PeopleMaintainMemberParam::getMemberId).collect(Collectors.toList());
                List<MemberDetailsResp> memberDetailsResps = memberFeignWrapper.queryMemberDetailList(memberIds);
                if (!CollectionUtils.isEmpty(memberDetailsResps)) {
                    List<String> memberNames = memberDetailsResps.stream().map(MemberDetailsResp::getMemberName).collect(Collectors.toList());
                    // 去除集合两边“[]”号
                    peopleMaintainMemberVO.setMemberNames(org.apache.commons.lang3.StringUtils.strip(memberNames.toString(), "[]"));
                }
            }
            return peopleMaintainMemberVOList;
        }
        return new ArrayList<>();
    }

    @Override
    public Result<List<ProcessMatrixMemberVO>> getMatrixPeopleMaintain(BaseMatrixPageParam param) {
        // 分页查询
        Page<ProcessMatrixMember> page = new Page<>(param.getPageNo(), param.getPageSize());
        IPage<ProcessMatrixMember> processMatrixMembers = workflowProcessMatrixMemberManager.page(page, new QueryWrapper<ProcessMatrixMember>().lambda()
                .eq(ProcessMatrixMember::getMatrixId, param.getMatrixId())
                .eq(ProcessMatrixMember::getIsDeleted, 0));
        if (ObjectUtils.isEmpty(processMatrixMembers) || CollectionUtils.isEmpty(processMatrixMembers.getRecords())) {
            return Result.build(new ArrayList<>());
        }
        // 循环解析数据
        List<ProcessMatrixMemberVO> processMatrixMemberVOList = new ArrayList<>();
        for (ProcessMatrixMember processMatrixMember : processMatrixMembers.getRecords()) {
            ProcessMatrixMemberVO processMatrixMemberVO = CopyObjectUtils.copyAtoB(processMatrixMember, ProcessMatrixMemberVO.class);
            List<PeopleMaintainMemberVO> peopleMaintainMemberVOList = this.jsonTransitionPeople(processMatrixMember.getRoleMember());
            if (!CollectionUtils.isEmpty(peopleMaintainMemberVOList)) {
                processMatrixMemberVO.setPeopleMaintainMembers(peopleMaintainMemberVOList);
            }
            processMatrixMemberVOList.add(processMatrixMemberVO);
        }

        return Result.build(processMatrixMemberVOList, processMatrixMembers.getTotal());
    }

    @Override
    public Result<ProcessMatrixMemberVO> saveMatrixPeopleMaintain(SaveMatrixPeopleMaintainParam param) {
        ProcessMatrixMember processMatrixMember = workflowProcessMatrixMemberManager.getById(param.getProcessMatrixId());
        if (StringUtils.isEmpty(processMatrixMember)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        processMatrixMember = CopyObjectUtils.copyAtoB(param, ProcessMatrixMember.class);
        processMatrixMember.setId(param.getProcessMatrixId());
        if (!CollectionUtils.isEmpty(param.getAddPeopleMaintainParams())) {
            processMatrixMember.setRoleMember(JSON.toJSONString(param.getAddPeopleMaintainParams()));
        }

        if (workflowProcessMatrixMemberManager.updateById(processMatrixMember)) {
            ProcessMatrixMemberVO processMatrixMemberVO = CopyObjectUtils.copyAtoB(processMatrixMember, ProcessMatrixMemberVO.class);
            processMatrixMemberVO.setPeopleMaintainMembers(this.jsonTransitionPeople(processMatrixMember.getRoleMember()));
            return Result.build(processMatrixMemberVO);
        }

        return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
    }

    @Override
    public Result<Boolean> deleteMatrixPeopleMaintain(List<Integer> processMatrixIds) {
        if (CollectionUtils.isEmpty(processMatrixIds)) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ErrorMsgEnum.NORMAL_ERR.getMsg());
        }

        List<ProcessMatrixMember> processMatrixMembers = workflowProcessMatrixMemberManager.listByIds(processMatrixIds);
        processMatrixMembers.forEach(processMatrixMember ->
                processMatrixMember.setIsDeleted(1)
        );

        return Result.build(workflowProcessMatrixMemberManager.updateBatchById(processMatrixMembers));
    }

    @Override
    public Result<List<PeopleMaintainMemberParam>> getMatrixRolePeopleMaintain(Integer matrixId, String roleName) {
        LambdaQueryWrapper<ProcessMatrixMember> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProcessMatrixMember::getMatrixId, matrixId);
        queryWrapper.eq(ProcessMatrixMember::getIsDeleted, 0);
        List<ProcessMatrixMember> processMatrixMemberList = workflowProcessMatrixMemberManager.list(queryWrapper);
        if (CollectionUtils.isEmpty(processMatrixMemberList)) {
            return Result.build(new ArrayList<>());
        }
        // 将角色人员信息去重PeopleMaintainMemberParam
        Set<PeopleMaintainMemberParam> peopleMaintainMemberParamSet = new HashSet<>();
        for (ProcessMatrixMember processMatrixMember : processMatrixMemberList) {
            if (!StringUtils.isEmpty(processMatrixMember.getRoleMember())) {
                Map<String, PeopleMaintainMemberVO> peopleMaintainMemberMap = this.jsonTransitionPeople(processMatrixMember.getRoleMember()).stream()
                        .collect(Collectors.toMap(PeopleMaintainMemberVO::getRoleName, p -> p));
                PeopleMaintainMemberVO peopleMaintainMemberVO = peopleMaintainMemberMap.get(roleName);
                if (!StringUtils.isEmpty(peopleMaintainMemberVO)) {
                    peopleMaintainMemberParamSet.addAll(peopleMaintainMemberVO.getPeopleMaintainMemberParams());
                }
            }
        }
        return Result.build(new ArrayList<>(peopleMaintainMemberParamSet));
    }

}
